package com.example.musicplayer.adapter;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.example.musicplayer.MusicScoreManager;
import com.example.musicplayer.R;
import com.example.musicplayer.musicClass.MusicInfo;

import java.util.ArrayList;
import java.util.List;

public class MusicScoreItemAdapter extends BaseAdapter {
    private final List<MusicScoreManager.MusicScoreInfo> mLocalMusicScore;
    private final Context mContext;
    private final List<MusicScoreManager.MusicScoreInfo> mCurrentMusicScore;
    private int mSortType;
    private boolean mSortReverse;
    private boolean mOnlyScored;

    public MusicScoreItemAdapter(Context context) {
        mContext = context;
        mCurrentMusicScore = new ArrayList<>();
        if (MusicScoreManager.getInstance() != null) {
            mLocalMusicScore = MusicScoreManager.getInstance().getScoreList();
            mSortType = MusicScoreManager.getInstance().getSortType();
            mSortReverse = MusicScoreManager.getInstance().isSortReverse();
        } else {
            mLocalMusicScore = new ArrayList<>();
            mSortType = MusicScoreManager.SORT_DEFAULT;
            mSortReverse = false;
        }
        onSortChanged();
    }

    public void notifyMusicSortChanged(int sortType, boolean sortReverse, boolean onlyScored) {
        if (sortType != mSortType || sortReverse != mSortReverse || onlyScored != mOnlyScored) {
            mSortType = sortType;
            mSortReverse = sortReverse;
            mOnlyScored = onlyScored;
            onSortChanged();
            notifyDataSetChanged();
        }
    }

    public void notifyMusicScoreChanged(int position) {
        //check score
        if (position >= 0 && position < mCurrentMusicScore.size() && mCurrentMusicScore.get(position).getFinal() <= 0 &&
                mOnlyScored) {
            mCurrentMusicScore.remove(position);
        } else {
            if (mSortType != MusicScoreManager.SORT_DEFAULT) {
                if (position >= 1 && shouldSwapPosition(mCurrentMusicScore.get(position - 1), mCurrentMusicScore.get(position))) {
                    MusicScoreManager.MusicScoreInfo temp = mCurrentMusicScore.get(position);
                    for (int i = position - 1; i >= 0; i--) {
                        MusicScoreManager.MusicScoreInfo target = mCurrentMusicScore.get(i);
                        if (shouldSwapPosition(target, temp)) {
                            mCurrentMusicScore.set(i, temp);
                            mCurrentMusicScore.set(i + 1, target);
                        }
                    }
                } else if (position < mCurrentMusicScore.size() - 1 && shouldSwapPosition(mCurrentMusicScore.get(position),
                        mCurrentMusicScore.get(position + 1))) {
                    MusicScoreManager.MusicScoreInfo temp = mCurrentMusicScore.get(position);
                    for (int i = position + 1; i < mCurrentMusicScore.size(); i++) {
                        MusicScoreManager.MusicScoreInfo target = mCurrentMusicScore.get(i);
                        if (shouldSwapPosition(temp, target)) {
                            mCurrentMusicScore.set(i, temp);
                            mCurrentMusicScore.set(i - 1, target);
                        }
                    }
                }
            }
        }
        notifyDataSetChanged();
    }

    private void onSortChanged() {
        mCurrentMusicScore.clear();
        //if only display scored music
        if (mOnlyScored) {
            for (int i = 0; i < mLocalMusicScore.size(); i++) {
                if (mLocalMusicScore.get(i).getFinal() > 0) {
                    mCurrentMusicScore.add(mLocalMusicScore.get(i));
                }
            }
        } else {
            mCurrentMusicScore.addAll(mLocalMusicScore);
        }
        //check sort type
        if (mSortType != MusicScoreManager.SORT_DEFAULT) {
            for (int i = 1; i < mCurrentMusicScore.size(); i++) {
                MusicScoreManager.MusicScoreInfo temp = mCurrentMusicScore.get(i);
                for (int j = i - 1; j >= 0; j--) {
                    MusicScoreManager.MusicScoreInfo target = mCurrentMusicScore.get(j);
                    if (shouldSwapPosition(target, temp)) {
                        mCurrentMusicScore.set(j, temp);
                        mCurrentMusicScore.set(j + 1, target);
                    }
                }
            }
        } else if (mSortReverse) {
            mCurrentMusicScore.clear();
            for (int i = 0; i < mLocalMusicScore.size(); i++) {
                mCurrentMusicScore.add(mLocalMusicScore.get(mLocalMusicScore.size() - 1 - i));
            }
        }
    }

    private boolean shouldSwapPosition(MusicScoreManager.MusicScoreInfo pre, MusicScoreManager.MusicScoreInfo current) {
        if (pre == null || current == null) {
            return false;
        }
        boolean result;
        switch (mSortType) {
            case MusicScoreManager.SORT_LYRIC:
                result = pre.getLyric() < current.getLyric();
                break;
            case MusicScoreManager.SORT_MELODY:
                result = pre.getMelody() < current.getMelody();
                break;
            case MusicScoreManager.SORT_ARRANGEMENT:
                result = pre.getArrangement() < current.getArrangement();
                break;
            case MusicScoreManager.SORT_FAVOR:
                result = pre.getFavor() < current.getFavor();
                break;
            case MusicScoreManager.SORT_FINAL:
                result = pre.getFinal() < current.getFinal();
                break;
            case MusicScoreManager.SORT_DEFAULT:
            default:
                result = false;
                break;
        }
        return mSortReverse != result;
    }

    @Override
    public int getCount() {
        return mCurrentMusicScore == null ? 0 : mCurrentMusicScore.size();
    }

    @Override
    public Object getItem(int position) {
        return mCurrentMusicScore == null ? null : mCurrentMusicScore.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @SuppressLint("InflateParams")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.music_score_item, null);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    (int) mContext.getResources().getDimension(R.dimen.music_score_item_height));
            convertView.setLayoutParams(lp);
            viewHolder.mPosition = convertView.findViewById(R.id.position);
            viewHolder.mTitle = convertView.findViewById(R.id.title);
            viewHolder.mLyric = convertView.findViewById(R.id.score_lyric);
            viewHolder.mMelody = convertView.findViewById(R.id.score_melody);
            viewHolder.mArrangement = convertView.findViewById(R.id.score_arrangement);
            viewHolder.mFavor = convertView.findViewById(R.id.score_favor);
            viewHolder.mFinal = convertView.findViewById(R.id.score_final);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.bind(mContext, mCurrentMusicScore.get(position), position);
        return convertView;
    }

    static class ViewHolder {
        TextView mPosition;
        TextView mTitle;
        TextView mLyric;
        TextView mMelody;
        TextView mArrangement;
        TextView mFavor;
        TextView mFinal;

        public void bind(Context context, MusicScoreManager.MusicScoreInfo musicScoreInfo, int position) {
            String text = (position + 1) + "";
            mPosition.setText(text);
            if (musicScoreInfo != null) {
                text = context.getResources().getString(R.string.score_lyric) + musicScoreInfo.getLyric();
                mLyric.setText(text);
                text = context.getResources().getString(R.string.score_melody) + musicScoreInfo.getMelody();
                mMelody.setText(text);
                text = context.getResources().getString(R.string.score_arrangement) + musicScoreInfo.getArrangement();
                mArrangement.setText(text);
                text = context.getResources().getString(R.string.score_favor) + musicScoreInfo.getFavor();
                mFavor.setText(text);
                text = context.getResources().getString(R.string.score_final) + musicScoreInfo.getFinal();
                mFinal.setText(text);
                MusicInfo musicInfo = MusicInfo.getMusicInfoById(musicScoreInfo.getID());
                if (musicInfo != null) {
                    text = musicInfo.getTitle() + " - " + musicInfo.getArtist();
                    mTitle.setText(text);
                }
            }
        }
    }
}